package net.alche.al.util.alches;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.Arrays;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 文件名称：加密相关操作 文件描述： 开发作者：姚礼武 创建日期：2018/11/1 17:08 文件版本：1.0
 */
public class ToolCrypto {
  public static void main222(String[] args) {
    ToolCrypto t = new ToolCrypto();
    String str = "123456";
    System.out.println("str=" + str);
    System.out.println("md5=" + t.getMD5(str));
  }

  // 定义加密算法，有DES、DESede(即3DES)、Blowfish
  // private static final String Algorithm = "DESede";
  // private static final String PASSWORD_CRYPT_KEY =
  // "2012PinganVitality075522628888ForShenZhenBelter075561869839";
  public static void test() {
    // des3
    byte[] bys = "yaoliwu".getBytes();
    String key = "hehe";
    byte[] enc = encryptMode(bys, key, "DESede");
    byte[] dec = decryptMode(enc, key, "DESede");
    System.out.println(Arrays.toString(bys));
    System.out.println(Arrays.toString(enc));
    System.out.println(Arrays.toString(dec));
  }

  /**
   * 获取MD5加密字符串
   * 
   * @param s 加密前的字符串
   * @return 加密后的字符串
   */
  public String getMD5(String s) {
    char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    try {
      byte[] strTemp = s.getBytes();
      MessageDigest mdTemp = MessageDigest.getInstance("MD5");
      mdTemp.update(strTemp);
      byte[] md = mdTemp.digest();
      int j = md.length;
      char str[] = new char[j * 2];
      int k = 0;
      for (int i = 0; i < j; i++) {
        byte byte0 = md[i];
        str[k++] = hexDigits[byte0 >>> 4 & 0xf];
        str[k++] = hexDigits[byte0 & 0xf];
      }
      return new String(str);
    } catch (Exception e) {
      return null;
    }
  }

  /**
   * 加密3des密码串
   * 
   * @param value 需要加密的值
   * @param key   加密key
   * @return 加密后的字符串
   */
  public String encrypt3DES(String value, String key) {
    byte[] bytes = value.getBytes(Charset.forName("utf-8"));
    byte[] back = encryptMode(bytes, key, "DESede");
    try {
      return new String(back, "ISO-8859-1");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return null;
  }

  /**
   * 解密加密3des密码串
   * 
   * @param encryptedStr 需要解密密的字符串
   * @param key          加密key
   * @return 加密后的字符串
   */
  public String decrypt3DES(String encryptedStr, String key) {
    byte[] bytes = null;
    try {
      bytes = encryptedStr.getBytes("ISO-8859-1");
    } catch (Exception e) {
    }
    byte[] back = decryptMode(bytes, key, "DESede");
    return new String(back, Charset.forName("utf-8"));
  }

  /**
   * 加密方法
   * 
   * @param src 源数据的字节数组
   * @return
   */
  private static byte[] encryptMode(byte[] src, String key, String Algorithm) {
    try {
      SecretKey deskey = new SecretKeySpec(build3DesKey(key), Algorithm); // 生成密钥
      Cipher c1 = Cipher.getInstance(Algorithm); // 实例化负责加密/解密的Cipher工具类
      c1.init(Cipher.ENCRYPT_MODE, deskey); // 初始化为加密模式
      return c1.doFinal(src);
    } catch (java.security.NoSuchAlgorithmException e1) {
      e1.printStackTrace();
    } catch (javax.crypto.NoSuchPaddingException e2) {
      e2.printStackTrace();
    } catch (Exception e3) {
      e3.printStackTrace();
    }
    return null;
  }

  /**
   * 解密函数
   * 
   * @param src 密文的字节数组
   * @return
   */
  private static byte[] decryptMode(byte[] src, String key, String Algorithm) {
    try {
      SecretKey deskey = new SecretKeySpec(build3DesKey(key), Algorithm);
      Cipher c1 = Cipher.getInstance(Algorithm);
      c1.init(Cipher.DECRYPT_MODE, deskey); // 初始化为解密模式
      return c1.doFinal(src);
    } catch (java.security.NoSuchAlgorithmException e1) {
      e1.printStackTrace();
    } catch (javax.crypto.NoSuchPaddingException e2) {
      e2.printStackTrace();
    } catch (Exception e3) {
      e3.printStackTrace();
    }
    return null;
  }

  /*
   * 根据字符串生成密钥字节数组
   * 
   * @param keyStr 密钥字符串
   * 
   * @return
   * 
   * @throws UnsupportedEncodingException
   */
  private static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
    byte[] key = new byte[24]; // 声明一个24位的字节数组，默认里面都是0
    byte[] temp = keyStr.getBytes("UTF-8"); // 将字符串转成字节数组

    /*
     * 执行数组拷贝 System.arraycopy(源数组，从源数组哪里开始拷贝，目标数组，拷贝多少位)
     */
    if (key.length > temp.length) {
      // 如果temp不够24位，则拷贝temp数组整个长度的内容到key数组中
      System.arraycopy(temp, 0, key, 0, temp.length);
    } else {
      // 如果temp大于24位，则拷贝temp数组24个长度的内容到key数组中
      System.arraycopy(temp, 0, key, 0, key.length);
    }
    return key;
  }

}
